/*
 * Scene.cpp
 *
 *  Created on: May 28, 2011
 *      Author: Ernest Mashele <mashern@gmail.com>
 */

#include "Renderer.h"

Scene::Scene() :
	pMaterial(0), pD3D(0), pCamera(0), pModel(0), pShader(0)
{
}

Scene::~Scene()
{
}

bool Scene::Initialize(HWND hWnd)
{
	pD3D = new Direct3D;
	if (!pD3D)
	{
		return false;
	}

	if (!pD3D->Initialize(hWnd))
		return false;

	pCamera = new Camera;
	if (!pCamera)
	{
		return false;
	}

	pModel = new Model;
	if (!pModel)
	{
		return false;
	}

	if (!pModel->Initialize(pD3D->GetDevice(), L"data/seafloor.dds",
			"data/cube.txt"))
		return false;

	// Create the light shader object.
	pShader = new Shader;
	if (!pShader)
	{
		return false;
	}

	// Initialize the light shader object.
	if (!pShader->Initialize(pD3D->GetDevice(), hWnd))
	{
		return false;
	}

	pMaterial = new Material;
	if (!pMaterial)
		return false;

	return true;
}

void Scene::Shutdown()
{
	if (pMaterial)
	{
		delete pMaterial;
		pMaterial = 0;
	}

	ReleaseClass(pShader);

	// Release the model object.
	if (pModel)
	{
		pModel->Shutdown();
		delete pModel;
		pModel = 0;
	}

	// Release the camera object.
	if (pCamera)
	{
		delete pCamera;
		pCamera = 0;
	}

	// Release the Direct3D object.
	if (pD3D)
	{
		pD3D->Shutdown();
		delete pD3D;
		pD3D = 0;
	}

	return;
}

void Scene::Render()
{
	pCamera->SetPosition(0.0f, 0.0f, -10.0f);
	D3DXMATRIX View, Projection, World;
	static float rotation = 0.0f;

	pD3D->BeginScene();
	pCamera->Render();

	pCamera->GetViewMatrix(View);
	pD3D->GetProjectionMatrix(Projection);
	pD3D->GetWorldMatrix(World);

	// Update the rotation variable each frame.
	static DWORD dwTimeStart = 0;
	DWORD dwTimeCur = GetTickCount();
	if (dwTimeStart == 0)
		dwTimeStart = dwTimeCur;
	rotation = (dwTimeCur - dwTimeStart) / 1000.0f;

	D3DXMatrixRotationY(&World, rotation);

	// Put the model vertex and index buffers on the graphics pipeline to prepare them for drawing.
	pModel->Render(pD3D->GetDevice());

	// Render the model using the light shader.
	pShader->Render(pD3D->GetDevice(), pModel->GetIndexCount(), World, View,
			Projection, pModel->GetTexture(), pCamera->GetPosition(),
			D3DXVECTOR3(0.0f, 0.0f, 1.0f), pMaterial->getAmbientColour(),
			pMaterial->getDiffuseColour(), pMaterial->getSpecularColour(),
			pMaterial->getSpecularPower());

	// Present the rendered scene to the screen.
	pD3D->EndScene();

	return;
}

LRESULT CALLBACK Scene::MessageHandler(HWND hWnd, UINT message, WPARAM wParam,
		LPARAM lParam)
{
	switch (message)
	{
	case WM_KEYDOWN:
	{
		break;
	}
	case WM_KEYUP:
	{
		break;
	}
	default:
	{
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	}

	return 0;
}
